home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 376-400 / disk_386 / xlispstat / src2.lzh / XLisp-Stat / xsgraphics.c < prev    next >
C/C++ Source or Header  |  1990-10-04  |  16KB  |  587 lines

  1. /* xsgraphics - XLISP interface to IVIEW dynamic graphics package.     */
  2. /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney                  */
  3. /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
  4. /* You may give out copies of this software; for conditions see the    */
  5. /* file COPYING included with this distribution.                       */
  6.  
  7. #include <string.h>
  8. #include "xlisp.h"
  9. #include "osdef.h"
  10. #ifdef ANSI
  11. #include "xlproto.h"
  12. #include "xlsproto.h"
  13. #include "iviewproto.h"
  14. #include "Stproto.h"
  15. #else
  16. #include "xlfun.h"
  17. #include "xlsfun.h"
  18. #include "iviewfun.h"
  19. #include "Stfun.h"
  20. #endif ANSI
  21. #include "xlsvar.h"
  22.  
  23. /* forward declarations */
  24. #ifdef ANSI
  25. LVAL base_is_state(void),is_state(void),internal_is_state(int),
  26.      base_visible_range(void),visible_range(void),base_scale_to_range(void),
  27.      scale_to_range(void),base_scale_shift(void),scale_shift(void),
  28.      iview_scale_shift(int),base_slice_variable(void),slice_variable(void),
  29.      iview_X_to_screen(int),iview_screen_to_X(int),internal_slice_variable(void),
  30.      iview_points_state(int);
  31. void drag_action(IVIEW_WINDOW,int,int);
  32. #else
  33. LVAL base_is_state(),is_state(),internal_is_state(),
  34.      base_visible_range(),visible_range(),base_scale_to_range(),
  35.      scale_to_range(),base_scale_shift(),scale_shift(),
  36.      iview_scale_shift(),base_slice_variable(),slice_variable()
  37.      iview_X_to_screen(),iview_screen_to_X(),
  38.      iview_points_state();
  39. void drag_action();
  40. #endif ANSI
  41.  
  42. /* static global variables */
  43. static int point_state;
  44. static IVIEW_WINDOW wind;
  45. static int scale_type;
  46. static LVAL plot_object;
  47.  
  48. static LVAL base_is_state()
  49. {
  50.   int point, set = FALSE, on;
  51.   PointState state;
  52.   
  53.   /* get the arguments */
  54.   point = getfixnum(xlgafixnum());
  55.   if (moreargs()) {
  56.     set = TRUE;
  57.     on = (xlgetarg() != NIL) ? TRUE : FALSE;
  58.   }
  59.   
  60.   /* set the new state if value was supplied */
  61.   if (set) {
  62.     if (on) {
  63.       switch (point_state) {
  64.       case 'S': IViewSetPointState(wind, point, pointSelected); break;
  65.       case 'H': IViewSetPointState(wind, point, pointHilited);  break;
  66.       case 'V': IViewSetPointState(wind, point, pointNormal);   break;
  67.       case 'M': IViewSetPointMask(wind, point, TRUE);           break;
  68.       }
  69.     }
  70.     else {
  71.       switch (point_state) {
  72.       case 'S': 
  73.       case 'H': IViewSetPointState(wind, point, pointNormal);   break;
  74.       case 'V':
  75.         if (IViewPointState(wind, point) != pointInvisible)
  76.           IViewSetPointState(wind, point, pointInvisible);
  77.         break;
  78.       case 'M': IViewSetPointMask(wind, point, FALSE);          break;
  79.       }
  80.     }
  81.   }
  82.   
  83.   /* get the current state */
  84.   state = IViewPointState(wind, point);
  85.   switch (point_state) {
  86.   case 'S': on = (state == pointSelected);      break;
  87.   case 'H': on = (state == pointHilited);       break;
  88.   case 'V': on = (state != pointInvisible);     break;
  89.   }
  90.     
  91.   /* return the current state */
  92.   return((on) ? s_true : NIL);
  93. }
  94.  
  95. static LVAL is_state()
  96. {
  97.   return(recursive_subr_map_elements(base_is_state, is_state));
  98. }
  99.  
  100. static LVAL internal_is_state(type)
  101.     int type;
  102. {
  103.   LVAL object, result;
  104.   int set = (xlargc > 2);
  105.   
  106.   object = xlgaobject();
  107.   wind = GETIVIEWADDRESS(object);
  108.   if (wind == nil) return(NIL);
  109.   if (xlargc > 1) IViewCheckLinks(wind);
  110.   point_state = type;
  111.   result = is_state();
  112.   
  113.   if (set) {
  114.     if (type == 'M') IViewRedrawContent(wind);
  115.     else IViewAdjustScreens(wind);
  116.   }
  117.   return(result);
  118. }
  119.  
  120. LVAL iview_point_selected()  { return(internal_is_state('S')); }
  121. LVAL iview_point_hilited()   { return(internal_is_state('H')); }
  122. LVAL iview_point_showing()   { return(internal_is_state('V')); }
  123.  
  124. #ifdef MACINTOSH
  125. LVAL iview_window_copy_to_clip()
  126. {
  127.   /*char*/ StGWWinInfo *gwinfo /* changed JKL */
  128.   
  129.   gwinfo = StGWObWinInfo(xlgaobject());
  130.   xllastarg();
  131.   if (gwinfo != nil) StGWCopyToClip(gwinfo);
  132.   return(NIL);
  133. }
  134. #endif MACINTOSH
  135.  
  136. static LVAL base_visible_range()
  137. {
  138.   int var;
  139.   double low, high;
  140.   
  141.   var = getfixnum(xlgafixnum());
  142.   xllastarg();
  143.   
  144.   IViewGetVisibleRange(wind, var, &low, &high);
  145.   return(double_list_2(low, high));
  146. }
  147.  
  148. static LVAL visible_range()
  149. {
  150.   return(recursive_subr_map_elements(base_visible_range, visible_range));
  151. }
  152.  
  153. LVAL iview_visible_range()
  154. {
  155.   LVAL object;
  156.   
  157.   object = xlgaobject();
  158.   wind = GETIVIEWADDRESS(object);
  159.   if (wind != nil) return(visible_range());
  160.   else return(NIL);
  161. }
  162.  
  163. static LVAL base_scale_to_range()
  164. {
  165.   int var;
  166.   double low, high;
  167.   
  168.   var = getfixnum(xlgafixnum());
  169.   low = makedouble(xlgetarg());
  170.   high = makedouble(xlgetarg());
  171.   
  172.   IViewScaleToRange(wind, var, low, high);  
  173.   return(NIL);
  174. }
  175.  
  176. static LVAL scale_to_range()
  177. {
  178.   return(recursive_subr_map_elements(base_scale_to_range, scale_to_range));
  179. }
  180.  
  181. LVAL iview_scale_to_range()
  182. {
  183.   LVAL arg;
  184.   
  185.   plot_object = xlgaobject();
  186.   wind = GETIVIEWADDRESS(plot_object);
  187.   if (wind != nil) scale_to_range();
  188.   if (! xlgetkeyarg(sk_draw, &arg)) arg = s_true;
  189.   if (arg != NIL) send_message(plot_object, sk_resize);
  190.   if (arg != NIL) send_message(plot_object, sk_redraw);
  191.   return(NIL);
  192. }
  193.  
  194. static LVAL base_scale_shift()
  195. {
  196.   int var, set = FALSE;
  197.   double scale, shift, old_scale, old_shift, new, new_scale, new_shift;
  198.   
  199.   var = getfixnum(xlgafixnum());
  200.   if (moreargs()) {
  201.     set = TRUE;
  202.     new = makedouble(xlgetarg());
  203.   }
  204.   
  205.   old_scale = IViewScale(wind, var);
  206.   old_shift = IViewShift(wind, var);
  207.   if (set) {
  208.     if (scale_type == 'A') {
  209.       if (new <= 0.0) xlfail("nonpositive scale factor");
  210.       new_scale = 1.0 / new;
  211.       new_shift = (old_scale != 0.0) ? old_shift * (new_scale / old_scale)
  212.                                      : 0.0;
  213.     }
  214.     else {
  215.       new_scale = old_scale;
  216.       new_shift = - new * old_scale;
  217.     }
  218.     if (old_scale == 0.0 || new_scale == 0.0) return(NIL);
  219.     scale = new_scale / old_scale;
  220.     shift = new_shift - scale * old_shift;
  221.   
  222.     IViewApplyScaleShift(wind, var, scale, shift);
  223.   }
  224.   if (scale_type == 'A') {
  225.     new = IViewScale(wind, var);
  226.     new = (new > 0.0) ? 1.0 / new : 1.0;
  227.   }
  228.   else new = (old_scale != 0.0) ? (-IViewShift(wind, var) / old_scale) : 0.0;
  229.   
  230.   return(cvflonum((FLOTYPE) new));
  231. }
  232.  
  233. static LVAL scale_shift()
  234. {
  235.   return(recursive_subr_map_elements(base_scale_shift, scale_shift));
  236. }
  237.  
  238. static LVAL iview_scale_shift(action)
  239.     int action;
  240. {
  241.   LVAL arg, result;
  242.   int set = (xlargc > 2);
  243.   
  244.   plot_object = xlgaobject();
  245.   wind = GETIVIEWADDRESS(plot_object);
  246.   scale_type = action;
  247.   
  248.   if (wind == nil) return(NIL);
  249.   
  250.   xlsave1(result);
  251.   result = scale_shift();
  252.   if (! xlgetkeyarg(sk_draw, &arg)) arg = s_true;
  253.   if (set && arg != NIL) send_message(plot_object, sk_resize);
  254.   if (set && arg != NIL) send_message(plot_object, sk_redraw);
  255.   xlpop();  
  256.   return(result);
  257. }
  258.  
  259. LVAL iview_scale()      { return(iview_scale_shift('A')); }
  260. LVAL iview_shift()      { return(iview_scale_shift('B')); }
  261.  
  262. LVAL iview_clear_masks()
  263. {
  264.   IVIEW_WINDOW w;
  265.   int i, n;
  266.   
  267.   w = GETIVIEWADDRESS(xlgaobject());
  268.   
  269.   if (w != nil) {
  270.     n = IViewNumPoints(w);
  271.     for (i = 0; i < n; i++) IViewSetPointMask(w, i, FALSE);
  272.     n = IViewNumLines(w);
  273.     for (i = 0; i < n; i++) IViewSetLineMask(w, i, FALSE);
  274. #ifdef USESTRINGS
  275.     n = IViewNumStrings(w);
  276.     for (i = 0; i < n; i++) IViewSetStringMask(w, i, FALSE);
  277. #endif /* USESTRINGS */
  278.   }
  279.   return(NIL);
  280. }
  281.  
  282.  
  283. static LVAL base_slice_variable()
  284. {
  285.   unsigned var;
  286.   int i, n;
  287.   double low, high, value;
  288.   
  289.   var = getfixnum(xlgafixnum());
  290.   low = makedouble(xlgetarg());
  291.   high = makedouble(xlgetarg());
  292.   xllastarg();
  293.   
  294.   if (var >= IViewNumVariables(wind)) return(NIL);
  295.     
  296.   n = IViewNumPoints(wind);
  297.   for (i = 0; i < n; i++) {
  298.     value = IViewPointValue(wind, var, i);
  299.     if (value < low || value > high) IViewSetPointMask(wind, i, TRUE);
  300.   }
  301.   n = IViewNumLines(wind);
  302.   for (i = 0; i < n; i++) {
  303.     value = IViewLineValue(wind, var, i);
  304.     if (value < low || value > high) IViewSetLineMask(wind, i, TRUE);
  305.   }
  306. #ifdef USESTRINGS
  307.   n = IViewNumStrings(wind);
  308.   for (i = 0; i < n; i++) {
  309.     value = IViewStringValue(wind, var, i);
  310.     if (value < low || value > high) IViewSetStringMask(wind, i, TRUE);
  311.   }
  312. #endif /* USESTRINGS */
  313.   return(NIL);
  314. }
  315.  
  316. static LVAL slice_variable()
  317. {
  318.   return(recursive_subr_map_elements(base_slice_variable, slice_variable));
  319. }
  320.  
  321. static LVAL internal_slice_variable()
  322. {
  323.   wind = GETIVIEWADDRESS(xlgaobject());
  324.   if (wind != nil) return(slice_variable());
  325.   else return(NIL);
  326. }
  327.  
  328. LVAL iview_slice_variable()      { return(internal_slice_variable()); }
  329.  
  330. static LVAL iview_X_to_screen(scaled)
  331.     int scaled;
  332. {
  333.   IVIEW_WINDOW w;
  334.   int x, y, var1, var2, screen_low, screen_high, origin_x, origin_y;
  335.   double dx, dy, low, high;
  336.   /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  337.   
  338.   w = GETIVIEWADDRESS(xlgaobject());
  339.   gwinfo = IViewWindowWinInfo(w);
  340.   dx = makedouble(xlgetarg());
  341.   dy = makedouble(xlgetarg());
  342.   xllastarg();
  343.   
  344.   if (w == nil) return(NIL);
  345.   
  346.   StGrGetContentOrigin(gwinfo, &origin_x, &origin_y);
  347.   StGrGetContentVariables(gwinfo, &var1, &var2);
  348.  
  349.   if (scaled) IViewGetScaledRange(w, var1, &low, &high);
  350.   else IViewGetRange(w, var1, &low, &high);
  351.   IViewGetScreenRange(w, var1, &screen_low, &screen_high);
  352.   if (low >= high) return(NIL);
  353.   x = (dx - low) * ((screen_high - screen_low) / (high - low)) + screen_low;
  354.   x = x + origin_x;
  355.    
  356.   if (scaled) IViewGetScaledRange(w, var2, &low, &high);
  357.   else IViewGetRange(w, var2, &low, &high);
  358.   IViewGetScreenRange(w, var2, &screen_low, &screen_high);
  359.   if (low >= high) return(NIL);
  360.   y = (dy - low) * ((screen_high - screen_low) / (high - low)) + screen_low;
  361.   y = origin_y - y;
  362.  
  363.   return(integer_list_2(x, y));
  364. }
  365.  
  366. static LVAL iview_screen_to_X(scaled)
  367.     int scaled;
  368. {
  369.   IVIEW_WINDOW w;
  370.   int x, y, var1, var2, screen_low, screen_high, origin_x, origin_y;
  371.   double dx, dy, low, high;
  372.   /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  373.   
  374.   w = GETIVIEWADDRESS(xlgaobject());
  375.   gwinfo = IViewWindowWinInfo(w);
  376.   x = getfixnum(xlgafixnum());
  377.   y = getfixnum(xlgafixnum());
  378.   xllastarg();
  379.   
  380.   if (w == nil) return(NIL);
  381.   
  382.   StGrGetContentOrigin(gwinfo, &origin_x, &origin_y);
  383.   StGrGetContentVariables(gwinfo, &var1, &var2);
  384.  
  385.   x = x - origin_x;
  386.   if (scaled) IViewGetScaledRange(w, var1, &low, &high);
  387.   else IViewGetRange(w, var1, &low, &high);
  388.   IViewGetScreenRange(w, var1, &screen_low, &screen_high);
  389.   if (screen_low >= screen_high) return(NIL);
  390.   dx = (x - screen_low) * ((high - low) / (screen_high - screen_low)) + low;
  391.    
  392.   y = origin_y - y;
  393.   if (scaled) IViewGetScaledRange(w, var2, &low, &high);
  394.   else IViewGetRange(w, var2, &low, &high);
  395.   IViewGetScreenRange(w, var2, &screen_low, &screen_high);
  396.   if (screen_low >= screen_high) return(NIL);
  397.   dy = (y - screen_low) * ((high - low) / (screen_high - screen_low)) + low;
  398.  
  399.   return(double_list_2(dx, dy));
  400. }
  401.  
  402. LVAL iview_real_to_screen()   { return(iview_X_to_screen(FALSE)); }
  403. LVAL iview_scaled_to_screen() { return(iview_X_to_screen(TRUE));  }
  404.  
  405. LVAL iview_screen_to_real()   { return(iview_screen_to_X(FALSE)); }
  406. LVAL iview_screen_to_scaled() { return(iview_screen_to_X(TRUE));  }
  407.  
  408. LVAL iview_points_in_rect()
  409. {
  410.   IVIEW_WINDOW w;
  411.   int left, top, width, height, i, n;
  412.   LVAL object, result, temp;
  413.   
  414.   object = xlgaobject();
  415.   w = GETIVIEWADDRESS(object);
  416.   left = getfixnum(xlgafixnum());
  417.   top = getfixnum(xlgafixnum());
  418.   width = getfixnum(xlgafixnum());
  419.   height = getfixnum(xlgafixnum());
  420.   xllastarg();
  421.  
  422.   if (w == nil) return(NIL);
  423.   
  424.   xlstkcheck(2);
  425.   xlsave(result);
  426.   xlsave(temp);
  427.   IViewClearPointMarks(w);
  428.   IViewMarkPointsInRect(w, left, top, width, height);
  429.   n = IViewNumPoints(w);
  430.   for (i = 0, result = NIL; i < n; i++)
  431.     if (IViewPointMarked(w, i)) {
  432.       temp = cvfixnum((FIXTYPE) i);
  433.       result = cons(temp, result);
  434.     }
  435.   IViewClearPointMarks(w);
  436.   xlpopn(2);
  437.   
  438.   return(result);
  439. }
  440.  
  441. static struct { 
  442.   int left, top, width, height, off_x, off_y;
  443. } grey_rect;
  444.  
  445. static void drag_action(w, x, y)
  446.     IVIEW_WINDOW w;
  447.     int x, y;
  448. {
  449.   /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
  450.   
  451.   StGWFrameRect(gwinfo, grey_rect.left, grey_rect.top,
  452.                         grey_rect.width, grey_rect.height);
  453.   grey_rect.left = x - grey_rect.off_x;
  454.   grey_rect.top = y - grey_rect.off_y;
  455.   StGWFrameRect(gwinfo, grey_rect.left, grey_rect.top,
  456.                         grey_rect.width, grey_rect.height);
  457. }
  458.   
  459. LVAL iview_window_drag_grey_rect()
  460. {
  461.   LVAL object;
  462.   IVIEW_WINDOW w;
  463.   int mode, type;
  464.   /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
  465.   
  466.   object = xlgaobject();
  467.   w = GETIVIEWWINDOWADDRESS(object);
  468.   gwinfo = StGWObWinInfo(object);
  469.   if (w == nil || gwinfo == nil) return(NIL);
  470.   
  471.   grey_rect.left = getfixnum(xlgafixnum());
  472.   grey_rect.top = getfixnum(xlgafixnum());
  473.   grey_rect.width = getfixnum(xlgafixnum());
  474.   grey_rect.height = getfixnum(xlgafixnum());
  475.   grey_rect.off_x = (moreargs()) ? getfixnum(xlgafixnum()) : grey_rect.width;
  476.   grey_rect.off_y = (moreargs()) ? getfixnum(xlgafixnum()) : grey_rect.height;
  477.   xllastarg();
  478.  
  479.   mode = StGWDrawMode(gwinfo);
  480.   StGWSetDrawMode(gwinfo, 1);
  481.   type = StGWLineType(gwinfo);
  482.   StGWSetLineType(gwinfo, 1);
  483.   
  484.   grey_rect.left -= grey_rect.off_x;
  485.   grey_rect.top -= grey_rect.off_y;
  486.  
  487.   StGWFrameRect(gwinfo, grey_rect.left, grey_rect.top,
  488.                         grey_rect.width, grey_rect.height);
  489.  
  490.  
  491.   StGWWhileButtonDown(gwinfo, drag_action, TRUE);
  492.  
  493.   StGWFrameRect(gwinfo, grey_rect.left, grey_rect.top,
  494.                         grey_rect.width, grey_rect.height);
  495.  
  496.   StGWSetDrawMode(gwinfo, mode);
  497.   StGWSetLineType(gwinfo, type);
  498.  
  499.   return(integer_list_4(grey_rect.left, grey_rect.top,
  500.                         grey_rect.width, grey_rect.height));
  501. }
  502.  
  503. static LVAL iview_points_state(which)
  504.     int which;
  505. {
  506.   IVIEW_WINDOW w;
  507.   LVAL points, next;
  508.   int set, i, n;
  509.   PointState state;
  510.   
  511.   switch(which) {
  512.   case 'V': state = pointInvisible; break;
  513.   case 'H': state = pointHilited; break;
  514.   case 'S': state = pointSelected; break;
  515.   }
  516.   
  517.   w = GETIVIEWADDRESS(xlgaobject());
  518.   set = moreargs();
  519.   points = (set) ? xlgalist() : NIL;
  520.   xllastarg();
  521.   
  522.   if (w != nil) {
  523.     IViewCheckLinks(w);
  524.     n = IViewNumPoints(w);
  525.     if (set) {
  526.       IViewClearPointMarks(w);
  527.       for (next = points; consp(next) && fixp(car(next)); next = cdr(next)) {
  528.          i = getfixnum(car(next));
  529.          if (0 <= i && i < n) IViewSetPointMark(w, i, TRUE);
  530.       }
  531.       switch(which) {
  532.       case 'V':
  533.         for (i = 0; i < n; i++) {
  534.           if (! IViewPointMasked(w, i)) {
  535.             if (IViewPointMarked(w, i) && IViewPointState(w, i) == pointInvisible)
  536.               IViewSetPointState(w, i, pointNormal);
  537.             else if (! IViewPointMarked(w, i) && IViewPointState(w, i) != pointInvisible)
  538.               IViewSetPointState(w, i, pointInvisible);
  539.           }
  540.         }
  541.         break;
  542.       case 'H':
  543.         for (i = 0; i < n; i++) {
  544.           if (! IViewPointMasked(w, i)) {
  545.             if (IViewPointMarked(w, i) && IViewPointState(w, i) == pointNormal)
  546.               IViewSetPointState(w, i, pointHilited);
  547.             else if (! IViewPointMarked(w, i) && IViewPointState(w, i) != pointHilited)
  548.               IViewSetPointState(w, i, pointNormal);
  549.           }
  550.         }
  551.         break;
  552.       case 'S':
  553.         for (i = 0; i < n; i++) {
  554.           if (! IViewPointMasked(w, i) && IViewPointState(w, i) != pointInvisible) {
  555.             if (IViewPointMarked(w, i)) IViewSetPointState(w, i, pointSelected);
  556.             else IViewSetPointState(w, i, pointNormal);
  557.           }
  558.         }
  559.         break;
  560.       }
  561.       IViewAdjustScreens(w);
  562.     }
  563.     else {
  564.       xlsave1(points);
  565.       switch(which) {
  566.       case 'V':
  567.         for (i = n - 1, points = NIL; i >= 0; i--)
  568.           if (IViewPointState(w, i) != pointInvisible)
  569.             points = cons(cvfixnum((FIXTYPE) i), points);
  570.         break;
  571.       case 'H':
  572.       case 'S':
  573.         for (i = n - 1, points = NIL; i >= 0; i--)
  574.           if (IViewPointState(w, i) == state)
  575.             points = cons(cvfixnum((FIXTYPE) i), points);
  576.         break;
  577.       }
  578.       xlpop();
  579.     }
  580.   }
  581.   return(points);
  582. }
  583.  
  584. LVAL iview_points_showing()  { return(iview_points_state('V')); }
  585. LVAL iview_points_hilited()  { return(iview_points_state('H')); }
  586. LVAL iview_points_selected() { return(iview_points_state('S')); }
  587.